package com.apobates.jforum2.troll.nest.controller;

import com.apobates.jforum2.troll.accounts.stub.vo.MemberVo;
import com.apobates.jforum2.troll.nest.service.LetterClient;
import com.apobates.jforum2.troll.nest.service.MemberClient;
import com.apobates.jforum2.troll.notices.stub.vo.LetterDigestVo;
import com.apobates.jforum2.troll.notices.stub.vo.LetterInboxNoticeVo;
import com.apobates.jforum2.troll.notices.stub.vo.LetterInboxVo;
import com.apobates.jforum2.troll.notices.stub.vo.LetterOutboxVo;
import com.apobates.jforum2.troll.utils.core.Commons;
import com.apobates.jforum2.troll.utils.core.DateTimeUtils;
import com.apobates.jforum2.troll.utils.core.EntityPageResult;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.http.MediaType;
import org.springframework.http.ResponseEntity;
import org.springframework.web.bind.annotation.*;
import org.springframework.web.servlet.mvc.method.annotation.SseEmitter;
import java.util.List;
import java.util.Map;

/**
 * 内部消息API控制器
 * 注意: 需要带有服务响应的状态码使用ResponseEntity, 对于返回值对象的请求在失败时返回404,对于String响应的操作返回401
 * @author xiaofanku
 * @since 20210412
 */
@RestController
@RequestMapping("/api/letter")
public class LetterClientController {
    @Autowired
    private LetterClient letterClient;
    @Autowired
    private MemberClient memberClient;
    private final static Logger logger = LoggerFactory.getLogger(LetterClientController.class);

    //1.指定日期以来未坊的信件
    @GetMapping("/recent/{member}/{sender}/{stamp}")
    public List<LetterDigestVo> getLetterForPrevious(
            @PathVariable("member") long memberId,
            @PathVariable("sender") long sender,
            @PathVariable("stamp") int previousUx){
        return letterClient.getByPrevious(memberId, sender, previousUx);
    }

    //2.聊天界面中的记录
    @GetMapping("/chat/{member}/{sender}/{page}/{number}")
    public EntityPageResult<LetterDigestVo> getMutualLetter(
            @PathVariable("member") long memberId,
            @PathVariable("sender") long sender,
            @PathVariable("page") int page,
            @PathVariable("number") int pageSize){
        return letterClient.getMutual(memberId, sender, page, pageSize);
    }

    //3.会员的收件箱
    @GetMapping("/inbox/{member}/{page}/{number}")
    public EntityPageResult<LetterInboxVo> getLetterInbox(
            @PathVariable("member") long memberId,
            @PathVariable("page") int page,
            @PathVariable("number") int pageSize){
        return letterClient.getInbox(memberId, page, pageSize);
    }

    //4.会员的发件箱
    @GetMapping("/outbox/{member}/{typed}/{page}/{number}")
    public EntityPageResult<LetterOutboxVo> getLetterOutbox(
            @PathVariable("member") long memberId,
            @PathVariable("typed") int typeEnumSymbol,
            @PathVariable("page") int page,
            @PathVariable("number") int pageSize){
        return letterClient.getOutbox(memberId, typeEnumSymbol, page, pageSize);
    }

    //5.发送消息
    @PostMapping(value="/sent", consumes="application/x-www-form-urlencoded")
    public ResponseEntity<LetterDigestVo> sendLetter(
            @RequestParam("sender")long sender,
            @RequestParam("nickname")String senderNickname,
            @RequestParam("subject")String subject,
            @RequestParam("message")String content,
            @RequestParam("receiver")long receiver){
        try {
            ResponseEntity<MemberVo> responseEntity = memberClient.get(receiver);
            MemberVo mv = responseEntity.getBody();
            return letterClient.send(sender, senderNickname, subject, content, receiver, mv.getNickname());
        }catch (Exception e){
            logger.error("[nest-letter-send]ResponseEntity exception:"+e.getMessage());
        }
        return ResponseEntity.notFound().build();
    }

    //6.收件箱中标记信件为已读
    @PutMapping(value = "/inbox/{member}/readed/all", consumes="application/x-www-form-urlencoded")
    public boolean readAllLetter(
            @PathVariable("member")long memberId,
            @RequestParam("target")long othMember,
            @RequestParam("direction")int direction){
        return letterClient.readAll(memberId, othMember, direction);
    }

    //7.收件箱中标记信件为已读
    @PutMapping(value = "/inbox/{member}/readed", consumes = "application/x-www-form-urlencoded")
    public boolean readedLetter(
            @PathVariable("member")long memberId,
            @RequestParam("records")String idString){
        return letterClient.readed(memberId, idString);
    }

    //8.收件箱中未读的信件数量
    @GetMapping("/inbox/{member}/unreaded/size")
    public long getUnReadLetterSize(@PathVariable("member")long memberId){
        return letterClient.getUnReadSize(memberId);
    }

    //9.收件箱中指定发件人发来的未读的信件数量
    @GetMapping("/inbox/{member}/sender/{sender}/unreaded/size")
    public long getUnReadLetterSize(@PathVariable("member")long memberId, @PathVariable("sender")long senderId){
        return letterClient.getUnReadSize(memberId, senderId);
    }

    //10.收件箱中发件人发来的未读数量
    @PostMapping(value="/inbox/{member}/unreaded", consumes="application/x-www-form-urlencoded")
    public Map<Long,Long> getInboxSenderUnreads(
            @PathVariable("member")long memberId,
            @RequestParam("records")String senderIdString){
        return letterClient.getInboxSenderUnreads(memberId, senderIdString);
    }

    //11.收件箱中发件人发来的未读数量
    @PostMapping(value = "/inbox/{member}/unreaded/collect", consumes="application/x-www-form-urlencoded")
    public List<LetterInboxNoticeVo> getInboxSenderUnreadsCollect(
            @PathVariable("member")long memberId,
            @RequestParam("records")String senderIdString){
        return letterClient.getInboxSenderUnreadsCollect(memberId, senderIdString);
    }

    //12.今日的通知
    @GetMapping("/today/claim")
    public List<LetterDigestVo> getTodayClaim(){
        return letterClient.getTodayClaim();
    }

    //使用SSE获取指定收件人未读的消息
    //Angular采用的
    @GetMapping(value = "/inbox/{member}/notice", produces = MediaType.TEXT_EVENT_STREAM_VALUE)
    public SseEmitter getMessageUnreadNotice(@PathVariable("member") long memberId) {
        SseEmitter emitter = new SseEmitter(12000L);
        try {
            SseEmitter.SseEventBuilder event = SseEmitter.event()
                    .data(letterClient.getUnReadSize(memberId))
                    .id(DateTimeUtils.getUnixTimestamp()+""+Commons.randomNumeric(4))
                    .name("UnReadMessages");
            emitter.send(event);
        } catch (Exception ex) {
            emitter.completeWithError(ex);
        } finally {
            emitter.complete();
        }
        return emitter;
    }
}
/*
/letter/recent/{member}/{sender}/{stamp}
/letter/outbox/{member}/{typed}/{page}/{number}
/letter/sent
/letter/chat/{member}/{sender}/{page}/{number}
/letter/inbox/{member}/{page}/{number}
/letter/inbox/{member}/readed/all
/letter/inbox/{member}/readed
/letter/inbox/{member}/unreaded/size
/letter/inbox/{member}/unreaded
/letter/inbox/{member}/unreaded/collect
/letter/inbox/{member}/sender/{sender}/unreaded/size
/letter/inbox/{member}/notice
/letter/today/claim
* */
